001 /* 002 * Copyright 2005 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.transit; 020 021 import java.rmi.RemoteException; 022 import java.util.EventObject; 023 import java.util.EventListener; 024 import java.util.Map; 025 import java.util.WeakHashMap; 026 027 import net.dpml.transit.monitor.LoggingAdapter; 028 029 import net.dpml.util.Logger; 030 import net.dpml.util.UnicastEventSource; 031 import net.dpml.util.EventQueue; 032 033 /** 034 * A abstract base class that established an event queue and handles event dispatch 035 * operations for listeners declared in classes extending this base class. 036 * 037 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 038 * @version 1.0.2 039 */ 040 public abstract class DefaultModel extends UnicastEventSource implements Disposable 041 { 042 // ------------------------------------------------------------------------ 043 // state 044 // ------------------------------------------------------------------------ 045 046 private Map m_listeners = new WeakHashMap(); 047 048 // ------------------------------------------------------------------------ 049 // constructor 050 // ------------------------------------------------------------------------ 051 052 /** 053 * Creation of a new model. 054 * @param queue the event queue 055 * @param name the name used to construct a logging channel 056 * @exception RemoteException if a remote exception occurs 057 */ 058 public DefaultModel( EventQueue queue, String name ) 059 throws RemoteException 060 { 061 this( queue, getLoggerForCategory( name ) ); 062 } 063 064 /** 065 * Creation of a new model. 066 * @param queue the event queue 067 * @param logger the assigned logging channel 068 * @exception NullPointerException if the supplied logging channel is null 069 * @exception RemoteException if a remote exception occurs 070 */ 071 public DefaultModel( EventQueue queue, Logger logger ) 072 throws NullPointerException, RemoteException 073 { 074 super( queue, logger ); 075 } 076 077 // ------------------------------------------------------------------------ 078 // DefaultModel 079 // ------------------------------------------------------------------------ 080 081 /** 082 * Return the assigned logging channel. 083 * @return the logging channel 084 */ 085 protected Logger getLogger() 086 { 087 return super.getLocalLogger(); 088 } 089 090 /** 091 * Dispose of the model. 092 */ 093 public synchronized void dispose() 094 { 095 EventListener[] listeners = getEventListeners(); 096 for( int i=0; i < listeners.length; i++ ) 097 { 098 EventListener listener = listeners[i]; 099 removeListener( listener ); 100 } 101 super.terminate(); 102 getLogger().debug( "disposed" ); 103 } 104 105 /** 106 * Enqueue an event for delivery to registered 107 * listeners unless there are no registered 108 * listeners. 109 * 110 * @param event the event object to add to the queue 111 * @param waitForCompletion if TRUE the implementation will apply 112 * the event to the event source event handler and return on 113 * copmpletion of evetn delivery 114 */ 115 protected void enqueueEvent( EventObject event, boolean waitForCompletion ) 116 { 117 if( m_listeners.size() > 0 ) 118 { 119 getEventQueue().enqueueEvent( event, waitForCompletion ); 120 } 121 } 122 123 /** 124 * Return a logging channel for the supplied name. 125 * @param name the name to use in construction of the logging channel 126 * @return the logging channel 127 */ 128 static Logger getLoggerForCategory( String name ) 129 { 130 if( null == name ) 131 { 132 return new LoggingAdapter( "" ); 133 } 134 else 135 { 136 return new LoggingAdapter( name ); 137 } 138 } 139 }